#include "test_prereq.h"

#include "disable_warning.h"

#ifdef TEST_MASK

#define TEST_MASK_000
#define TEST_MASK_001
#define TEST_MASK_002
#define TEST_MASK_003
#define TEST_MASK_004
#define TEST_MASK_005
#define TEST_MASK_006
#define TEST_MASK_007
#define TEST_MASK_008
#define TEST_MASK_009
#define TEST_MASK_010
#define TEST_MASK_011
#define TEST_MASK_012
#define TEST_MASK_013
#define TEST_MASK_014
#define TEST_MASK_015
#define TEST_MASK_016
#define TEST_MASK_017
#define TEST_MASK_018
#define TEST_MASK_019
#define TEST_MASK_020
#define TEST_MASK_021
#define TEST_MASK_022
#define TEST_MASK_023
#define TEST_MASK_024
#define TEST_MASK_025
#define TEST_MASK_026
#define TEST_MASK_027
#define TEST_MASK_028
#define TEST_MASK_029
#define TEST_MASK_030
#define TEST_MASK_031
#define TEST_MASK_032
#define TEST_MASK_033
#define TEST_MASK_034
#define TEST_MASK_035
#define TEST_MASK_036
#define TEST_MASK_037
#define TEST_MASK_038
#define TEST_MASK_039
#define TEST_MASK_040
#define TEST_MASK_041
#define TEST_MASK_042
#define TEST_MASK_043
#define TEST_MASK_044
#define TEST_MASK_045
#define TEST_MASK_046
#define TEST_MASK_047
#define TEST_MASK_048
#define TEST_MASK_049
#define TEST_MASK_050

//------------------------------------------------------------------------------------------------------//
namespace{
    typedef ::std::string Str;

    const bool no_file = false; 
    const bool for_file = true;
}
//------------------------------------------------------------------------------------------------------//

#ifdef TEST_MASK_000
TEST(os, mask_000)
{  
    {const Str mask = "*?m.?*";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "*?m.?*/";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "*?m.?* /";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?* /";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}
}
#endif // TEST_MASK_000

#ifdef TEST_MASK_001
TEST(os, mask_001)
{  
    {const Str mask = "*?m.?";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.?" , re );}

    {const Str mask = "*?m.?/";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.?" , re );}

    {const Str mask = "*?m.? /";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.?" , re );}

    {const Str mask = "  *?m.? /";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.?" , re );}

    {const Str mask = "  *?m.? ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.?" , re );}
}
#endif // TEST_MASK_001

#ifdef TEST_MASK_002
TEST(os, mask_002)
{  
    {const Str mask = "*?m.??";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.??" , re );}

    {const Str mask = " *?m.?? ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.??" , re );}

    {const Str mask = " *?m.?? /";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.??" , re );}

    {const Str mask = "*?m.??/";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.??" , re );}

    {const Str mask = "  *?m.??/";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.??" , re );}
}
#endif // TEST_MASK_002


#ifdef TEST_MASK_003
TEST(os, mask_003)
{  
    {const Str mask = "*?m.?*?";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*?  ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}
    
    {const Str mask = " *?m.?*?/";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = " *?m.?*? /";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "*?m.?*?/ ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*?  /  ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}
}
#endif // TEST_MASK_003

#ifdef TEST_MASK_004
TEST(os, mask_004)
{  
    {const Str mask = "  *?m.?*?";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*?/";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*? /";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*? / ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*? //";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*?/ ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}
}
#endif // TEST_MASK_004

//TEST(os, mask_007){ os::Mask m("");     EXPECT_EQ( "*m.*" , m.ToStr() ); }
#ifdef TEST_MASK_005
TEST(os, mask_005)
{  
    {const Str mask = "  *?m.?*?  ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*?  /";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*?  / ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}

    {const Str mask = "  *?m.?*?/  ";
    const Str re = os::OptimizeMask(mask);
    EXPECT_EQ( "*m.*" , re );}
}
#endif // TEST_MASK_005

#ifdef TEST_MASK_006
TEST(os, mask_006)
{  
    {const Str mask = "/a file";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eINCLUDE_A , key );}

    {const Str mask = "";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eINVALID_K , key );}

    {const Str mask = "/";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eINVALID_K , key );}

    {const Str mask = "/a f";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eINCLUDE_A , key );}
    
    {const Str mask = "/af";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eINVALID_K , key );}

    {const Str mask = "/f file";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eINCLUDE_F , key );}

    {const Str mask = "/d file";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eINCLUDE_D , key );}
}
#endif // TEST_MASK_006

#ifdef TEST_MASK_007
TEST(os, mask_007)
{  
    {const Str mask = "/!a file";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eEXCLUDE_A , key );}

    {const Str mask = "/!a ";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eEXCLUDE_A , key );}

    {const Str mask = "/!a";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eINVALID_K , key );}

    {const Str mask = "/!";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eINVALID_K , key );}

    {const Str mask = "/!f ";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eEXCLUDE_F , key );}

    {const Str mask = "/!d ";
    os::eKEY key = os::FindKey(mask);
    EXPECT_EQ( os::eEXCLUDE_D , key );}
}
#endif // TEST_MASK_007

#ifdef TEST_MASK_008
TEST(os, mask_008)
{  
    {Filter filter("/a *.*");
    EXPECT_EQ( 1 , filter.GetIncludes().size() );
    EXPECT_EQ( 0 , filter.GetExcludes().size() );}

    {Filter filter(" /a *.* ");
    EXPECT_EQ( 1 , filter.GetIncludes().size() );
    EXPECT_EQ( 0 , filter.GetExcludes().size() );}

}
#endif // TEST_MASK_008

#ifdef TEST_MASK_009
TEST(os, mask_009)
{  
    {Filter filter("/a *.* /f *.?");
    EXPECT_EQ( 2 , filter.GetIncludes().size() );
    EXPECT_EQ( 0 , filter.GetExcludes().size() );}

    {Filter filter(" /a   *.*  /f   *.?   ");
    EXPECT_EQ( 2 , filter.GetIncludes().size() );
    EXPECT_EQ( 0 , filter.GetExcludes().size() );}

    {Filter filter("/a *.* /f *.? /!d *" );
    EXPECT_EQ( 2 , filter.GetIncludes().size() );
    EXPECT_EQ( 1 , filter.GetExcludes().size() );}

    {Filter filter("/a *.* /f *.? /!d */a *.*" );
    EXPECT_EQ( 2 , filter.GetIncludes().size() );
    EXPECT_EQ( 1 , filter.GetExcludes().size() );}


    {Filter filter("/a *.* /!a *.* " );
    EXPECT_EQ( 1 , filter.GetIncludes().size() );
    EXPECT_EQ( 1 , filter.GetExcludes().size() );}

}
#endif // TEST_MASK_009

#ifdef TEST_MASK_010
TEST(os, mask_010)
{  
    EXPECT_EQ( true , Filter::Selected("mylib.txt", "*.txt") );
    EXPECT_EQ( false, Filter::Selected("mylib.txt", "*.lib") );
    EXPECT_EQ( true,  Filter::Selected("mylib.txt", "m*.t*") );
    EXPECT_EQ( false, Filter::Selected("lib.txt",   "m*.t*") );
    EXPECT_EQ( true,  Filter::Selected("mylib-32-d.lib", "*-32-d.lib") );
    EXPECT_EQ( false, Filter::Selected("mylib-32.lib",   "*-32-d.lib") );
}
#endif // TEST_MASK_010

#ifdef TEST_MASK_011
TEST(os, mask_011)
{  
    Filter::VecStr names;
    names.emplace_back("mylib2-32-r.lib");
    names.emplace_back("mylib-32-d.lib");
    names.emplace_back("mylib-64-d.lib");
    names.emplace_back("mylib-32.lib");
    names.emplace_back("mylib-64.lib");

    {const Filter::VecStr re = Filter::Selected(names, "*-32-d.lib");
    EXPECT_EQ( 1 , re.size() );}

    {const Filter::VecStr re = Filter::Selected(names, "*-32-r.lib");
    EXPECT_EQ( 1 , re.size() );}

    {const Filter::VecStr re = Filter::Selected(names, "*-64.lib");
    EXPECT_EQ( 1 , re.size() );}
}
#endif // TEST_MASK_011

#ifdef TEST_MASK_012
TEST(os, mask_012)
{  
    Filter f("/f PIC*.png /f PIC*.jpg");
    EXPECT_EQ( false, f.Selected("pic123.png",true) );
    EXPECT_EQ( true , f.Selected("PIC123.png",true) );
    EXPECT_EQ( false, f.Selected("PIC123.txt",true) );
    EXPECT_EQ( true , f.Selected("PIC123.jpg",true) );
    EXPECT_EQ( false, f.Selected("ship22.jpg",true) );
}
#endif // TEST_MASK_012

#ifdef TEST_MASK_013
TEST(os, mask_013)
{  
    Filter f("/f PIC*.png /f PIC*.jpg");
    Filter::VecStr names;
    names.emplace_back("pic123.png");
    names.emplace_back("PIC123.png");
    names.emplace_back("PIC123.txt");
    names.emplace_back("PIC123.jpg");
    names.emplace_back("PIC223.png");
    names.emplace_back("ship22.jpg");
    const Filter::VecStr re = f.Selected(names, true);
    EXPECT_EQ( 3, re.size() );
}
#endif // TEST_MASK_013

#ifdef TEST_MASK_014
TEST(os, mask_014)
{
    EXPECT_EQ( true,  Filter::Selected("mylib.lib",   "*.lib")    );
    EXPECT_EQ( false, Filter::Selected("mylib",       "*.lib")    ); 
    EXPECT_EQ( false, Filter::Selected("mylib.lib",   "*_d.lib")  ); 
    EXPECT_EQ( true,  Filter::Selected("mylib_d.lib", "*_d.lib")  ); 
    EXPECT_EQ( false, Filter::Selected("mylib_d",     "*_d.lib")  ); 
    EXPECT_EQ( false, Filter::Selected("mylib_d",     "**_d.lib") ); 
}
#endif // TEST_MASK_014

#ifdef TEST_MASK_015
TEST(os, mask_015)
{
    EXPECT_EQ( true,  Filter("/f *.lib").Selected("mylib.lib", for_file)  );
    EXPECT_EQ( false, Filter("/f *.lib").Selected("mylib",     for_file)  );
    EXPECT_EQ( true,  Filter("/d *").Selected("mylib",          no_file)  );
    EXPECT_EQ( false, Filter("/d *").Selected("mylib",         for_file)  );
}
#endif // TEST_MASK_015

#ifdef TEST_MASK_016
TEST(os, mask_016)
{
    EXPECT_EQ( false, Filter("/f *.lib /f *.txt").Selected("mylib.png",         for_file)   ); 
    EXPECT_EQ( true,  Filter("/f *.lib /f *.txt").Selected("mylib.lib",         for_file)   );
    EXPECT_EQ( true,  Filter("/f *.lib /f *.txt").Selected("mylib.txt",         for_file)   );
    EXPECT_EQ( false, Filter("/f *.lib /f *.txt").Selected("mylib.txt",          no_file)   );
    EXPECT_EQ( false, Filter("/f *.*  /!f *.txt").Selected("mylib.txt",          no_file)   );
    EXPECT_EQ( false, Filter("/f *.*  /!f *.txt").Selected("mylib.txt",         for_file)   ); 
    EXPECT_EQ( true,  Filter("/f *32.*  /!f *_d*.*").Selected("mylib_32.txt",   for_file)   ); 
    EXPECT_EQ( false, Filter("/f *32.*  /!f *_d*.*").Selected("mylib_d32.txt",  for_file)   ); 
    EXPECT_EQ( false, Filter("/a *32.*  /!a *_d*.*").Selected("mylib_d32.txt",  for_file)   ); 
    EXPECT_EQ( false, Filter("/a *32.*  /!a *_d*.*").Selected("mylib_d32.txt",   no_file)   ); 
    EXPECT_EQ( true, Filter("/a *.*").Selected("1.txt",      for_file)    ); 
    EXPECT_EQ( true, Filter("/a *").Selected("1",             no_file)    ); 
    EXPECT_EQ( true, Filter("/a *").Selected("1",             no_file)    ); 
    EXPECT_EQ( true, Filter("/a * /a *.*").Selected("1.txt", for_file)    ); 
    EXPECT_EQ( true, Filter("/a * /a *.*").Selected("1",      no_file)    ); 

    EXPECT_EQ( true, Filter("/f *_file*").Selected("hlink_file.txt", for_file) );
}
#endif // TEST_MASK_016

#ifdef TEST_MASK_017
TEST(os, mask_017)
{
    Filter filter = "/f *m?lib*";
    Filter::VecStr names;
    names.emplace_back("mylib");
    names.emplace_back("mylib1");
    names.emplace_back("mylib2");
    names.emplace_back("1mylib");
    names.emplace_back("1111");
    names.emplace_back("2222");
    const auto& r = filter.Selected(names,true);
    const auto num = r.size();
    EXPECT_EQ( 4, num );
}
#endif // TEST_MASK_017

#ifdef TEST_MASK_018
TEST(os, mask_018)
{
    Filter filter = "/f *m?lib* /!f 1*"; 
    Filter::VecStr names;
    names.emplace_back("mylib");
    names.emplace_back("mylib1");
    names.emplace_back("mylib2");
    names.emplace_back("1mylib");
    names.emplace_back("1111");
    names.emplace_back("2222");
    const auto& r = filter.Selected(names,true);
    const auto num = r.size();
    EXPECT_EQ( 3, num );
}    
#endif // TEST_MASK_018

#ifdef TEST_MASK_019
TEST(os, mask_019)
{
    const os::path& p = os::WhereProgramIsRunning();
    const path work = p/"../for_test";
    SetPath d,f;
    const os::str mask = "/f *.txt";
    EXPECT_EQ(true,  ScanDirectory(work,mask, d,f) );
    EXPECT_EQ(0,  d.size() );
    EXPECT_EQ(3,  f.size() );
}    
#endif // TEST_MASK_019
#ifdef TEST_MASK_020
TEST(os, mask_020)
{
    const os::path& p = os::WhereProgramIsRunning();
    const path work = p/"../for_test";
    SetPath d,f;
    const os::str mask = "/f *_file* /d *_dir*";
    EXPECT_EQ(true,  ScanDirectory(work,mask, d,f) );
    EXPECT_EQ(2,  d.size() );
    EXPECT_EQ(2,  f.size() );
}    
#endif // TEST_MASK_020
#ifdef TEST_MASK_021
TEST(os, mask_021)
{
    const os::path& p = os::WhereProgramIsRunning();
    const path work = p/"../for_test";
    SetPath d,f;
    const os::str mask = "/f *file* /!f h* /d * /!d j*";
    EXPECT_EQ(true, ScanDirectory(work, mask, d,f) );
    EXPECT_EQ(2,  d.size() );
    EXPECT_EQ(2,  f.size() );
}    
#endif // TEST_MASK_021
TEST(os, mask_022)
{
    const os::path& p = os::WhereProgramIsRunning();
    const path work = p/"../for_test";
    SetPath d,f;
    const os::str mask = " *.txt ";
    EXPECT_EQ(true, ScanDirectory(work, mask, d,f) );
    EXPECT_EQ(0,  d.size() );
    EXPECT_EQ(3,  f.size() );
}    

#ifdef TEST_MASK_022
#endif // TEST_MASK_022
#ifdef TEST_MASK_023
#endif // TEST_MASK_023
#ifdef TEST_MASK_024
#endif // TEST_MASK_024
#ifdef TEST_MASK_025
#endif // TEST_MASK_025
#ifdef TEST_MASK_026
#endif // TEST_MASK_026
#ifdef TEST_MASK_027
#endif // TEST_MASK_027
#ifdef TEST_MASK_028
#endif // TEST_MASK_028
#ifdef TEST_MASK_029
#endif // TEST_MASK_029
#ifdef TEST_MASK_030
#endif // TEST_MASK_030
#ifdef TEST_MASK_031
#endif // TEST_MASK_031
#ifdef TEST_MASK_032
#endif // TEST_MASK_032
#ifdef TEST_MASK_033
#endif // TEST_MASK_033
#ifdef TEST_MASK_034
#endif // TEST_MASK_034
#ifdef TEST_MASK_035
#endif // TEST_MASK_035
#ifdef TEST_MASK_036
#endif // TEST_MASK_036
#ifdef TEST_MASK_037
#endif // TEST_MASK_037
#ifdef TEST_MASK_038
#endif // TEST_MASK_038
#ifdef TEST_MASK_039
#endif // TEST_MASK_039
#ifdef TEST_MASK_040
#endif // TEST_MASK_040
#ifdef TEST_MASK_041
#endif // TEST_MASK_041
#ifdef TEST_MASK_042
#endif // TEST_MASK_042
#ifdef TEST_MASK_043
#endif // TEST_MASK_043
#ifdef TEST_MASK_044
#endif // TEST_MASK_044
#ifdef TEST_MASK_045
#endif // TEST_MASK_045
#ifdef TEST_MASK_046
#endif // TEST_MASK_046
#ifdef TEST_MASK_047
#endif // TEST_MASK_047
#ifdef TEST_MASK_048
#endif // TEST_MASK_048
#ifdef TEST_MASK_049
#endif // TEST_MASK_049
#ifdef TEST_MASK_050
#endif // TEST_MASK_050

#endif // TEST_MASK

#include "default_warning.h"

